#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

#include "crypto/types.h"
#include "crypto/tool.h"
#include "crypto/errors.h"

void ROL(unsigned int *s, unsigned short cx)
{
    if (cx > 32)
        cx %= 32;
    *s = ((*s) << cx) | ((*s) >> (32 - cx));
    return;
}

void LTOBL(uint64 *data)
{
    uint8 *indexPtr = (uint8 *)data;
    uint8 tmp;

    for (int i = 0; i < 4; i++)
    {
        uint8 tmp = *(indexPtr + i);
        *(indexPtr + i) = *(indexPtr + 7 - i);
        *(indexPtr + 7 - i) = tmp;
    }
}

void LTOB(uint *data)
{
    uint8 *indexPtr = (uint8 *)data;
    uint8 tmp = *indexPtr;
    *indexPtr = *(indexPtr + 3);
    *(indexPtr + 3) = tmp;
    indexPtr += 1;

    tmp = *indexPtr;
    *indexPtr = *(indexPtr + 1);
    *(indexPtr + 1) = tmp;
}

void BTOL(uint *data)
{
    uint8 *indexPtr = (uint8 *)data;
    uint8 tmp = *indexPtr;
    *indexPtr = *(indexPtr + 3);
    *(indexPtr + 3) = tmp;
    indexPtr += 1;

    tmp = *indexPtr;
    *indexPtr = *(indexPtr + 1);
    *(indexPtr + 1) = tmp;
}

bool isDigital(byte data)
{
    if (data < '0' || data > '9')
    {
        return false;
    }
    return true;
}

bool isZero(byte data)
{
    return data == '0' ? true : false;
}

int _strnlen(char *key, int len)
{
    assert(len >= 0);
    int i = 0;
    while (key[i] != '\0' && i < len)
    {
        i++;
    }
    return i;
}

int _strncmp(char *res, char *dst, int len)
{
    assert(len >= 0);
    int i = 0;
    while (!res[i] && !dst[i] && res[i] == dst[i] && i < len)
    {
        i++;
    }
    if (i == len)
    {
        return res[i - 1] - dst[i - 1];
    }
    return res[i] - dst[i];
}

void randomBuffer(void *buffer, int len)
{
    int fd = open("/dev/urandom", O_RDONLY);
    if (fd == -1)
    {
        export(CODE_FILE_OPERATE_FAILED, "File /dev/urandom open failed!");
    }
    read(fd, buffer, len);
    close(fd);
}

void randomBuf(void *buffer, int len, RandomFunc func)
{
    if (func == NULL)
    {
        randomBuffer(buffer, len);
    }
    else
    {
        func(buffer, len);
    }
}